using System;
using System.Collections.Generic;
using System.Reflection;
using Google.Protobuf;
using UnityEditor;

namespace HuaXianQu.ProtoBuffEx.ToolEditor
{
    public class ProtoBuffAssemblyRuntime
    {

        static List<Assembly> assemblies = new List<Assembly>();

        [InitializeOnLoadMethod]
        static void Initialize()
        {
            assemblies.Clear();
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                AssemblyName[] assemblyPaths = assembly.GetReferencedAssemblies();
                bool isAdd = false;
                foreach (var assemblyName in assemblyPaths)
                {
                    if (assemblyName.Name == "UnityEditor")
                    {
                        isAdd = false;
                        break;
                    }

                    //Google.Protobuf, Version=3.22.3.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604
                    if (assemblyName.Name == "Google.Protobuf")
                    {
                        isAdd = true;
                    }
                }

                if (isAdd)
                {
                    assemblies.Add(assembly);
                }
            }
        }

        // Assembly _assembly;
        static Lazy<ProtoBuffAssemblyRuntime> _protoBuffAssemblyRuntime = new Lazy<ProtoBuffAssemblyRuntime>();

        public static bool GetMessageTypeByAssembly(string name, out IMessage message, out Type type)
        {
            message = null;
            if (_protoBuffAssemblyRuntime.Value.GetMessageType(name, out type))
            {
                message = Activator.CreateInstance(type) as IMessage;
                return true;
            }

            return false;
        }

        private bool GetMessageType(string name, out Type type)
        {
            type = null;
            foreach (var asAssembly in assemblies)
            {
                type = asAssembly.GetType(name);
                if (type != null)
                {
                    return true;
                }
            }

            return false;
        }
    }
}